package cn.lingyangwl.agile.misc.statistic.service;

import cn.lingyangwl.framework.tool.core.*;
import cn.lingyangwl.framework.tool.core.exception.*;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author shenguangyang
 */
@Service
public class StatCacheServiceImpl implements StatCacheService {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    public String getCacheKey(String tenantId, String date, String entityName, String... fields) {
        // rt 表示实时统计
        StringBuilder key = new StringBuilder("statistic:rt:" + tenantId + ":" + entityName + ":" + date);
        for (String field : fields) {
            if (StringUtils.isEmpty(field)) {
                continue;
            }
            key.append(":").append(field);
        }
        return key.toString();
    }

    @Override
    public void incr(String tenantId, String entityName, String date, Long delta, String... fields) {
        String cacheKey = getCacheKey(tenantId, date, entityName, fields);
        redisTemplate.opsForValue().increment(cacheKey, delta);
        redisTemplate.expire(cacheKey, 2, TimeUnit.DAYS);
    }

    @Override
    public Long getIncr(String tenantId, String entityName, String date, String... fields) {
        String cacheKey = getCacheKey(tenantId, date, entityName, fields);
        Object cacheValue = redisTemplate.opsForValue().get(cacheKey);
        return convertValueType(cacheValue);
    }

    @Override
    public void hashIncr(String tenantId, String entityName, String date, String hashKey, Long delta, String... fields) {
        String cacheKey = getCacheKey(tenantId, date, entityName, fields);
        redisTemplate.opsForHash().increment(cacheKey, hashKey, delta);
        redisTemplate.expire(cacheKey, 2, TimeUnit.DAYS);
    }

    @Override
    public Map<String, Long> getHashIncr(String tenantId, String entityName, String date, String... fields) {
        Map<String, Long> respMap = new HashMap<>();
        String cacheKey = getCacheKey(tenantId, date, entityName, fields);
        redisTemplate.opsForHash().entries(cacheKey).forEach((k, v) -> respMap.put(String.valueOf(k), convertValueType(v)));
        return respMap;
    }

    public Long convertValueType(Object value) {
        if (Objects.isNull(value)) {
            return 0L;
        }
        if (value instanceof Integer) {
            return ((Integer) value).longValue();
        } else if (value instanceof Long) {
            return (Long) value;
        } else if (value instanceof Double) {
            return ((Double) value).longValue();
        } else {
            throw new BizException("不支持的缓存类型 {}", value.getClass().getSimpleName());
        }
    }
}
